home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
GOFER
/
scripts
/
Modular
< prev
next >
Wrap
Text File
|
1993-11-25
|
2KB
|
61 lines
-------------------- Modular arithmetic --------------------
p :: Int
p = 7 -- change this appropriately
----------- Datatypes --------------------
data Residue = Res Int
----------- Instance declarations ---------
instance Eq Residue where
(Res x) == (Res y) = (x-y) `mod` p == 0
instance Mult Residue where
unit = Res 1
instance LeftMul Residue Residue where
(Res x) * (Res y) = Res ((x*y) `mod` p)
instance LeftMul Int Residue where
n * (Res x) = (Res n) * (Res x)
instance Add Residue where
(Res x) + (Res y) = Res ((x+y) `mod` p)
(Res x) - (Res y) = Res ((x-y) `mod` p)
zero = Res 0
instance Div Residue Residue where
(Res x) / (Res y) = Res ((x*u) `mod` p) where
(1,u,_) = gcdplus y p
instance Div Residue Int where
x / n = x / (Res (n `mod` p))
--------- Definitions --------------------
--- gcdplus x y == (d,u,v) where u*x+v*y == d ( == hcf x y )
gcdplus :: Int -> Int -> (Int,Int,Int)
gcdplus x y | y == 0 = (x, 1, 0)
| otherwise = (d, v, u-v*(x/y))
where (d, u, v) = gcdplus y (x `mod` y)
--- x^(order x) == 1 modulo p
order :: Residue -> Int
order x = 1 + length (takeWhile (/= unit) [ x^n | n <- [1..]])
--- every x == primGen^n modulo p for some n, if x /= 0 modulo p
primGen :: Residue
primGen = Res g
where g = while (\x -> (order (Res x) /= (p-1))) (+1) 2
length x = sum [ 1 | _ <- x ]
while :: (a -> Bool) -> (a -> a) -> a -> a
while p f x | p x = while p f (f x)
| otherwise = x
------ End Modular